package org.rescue.analysis.taxonomy;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.rescue.Dag.Concept;
import org.rescue.Dag.DAGNode;
import org.rescue.Dag.DirectedAcyclicGraph;
import org.rescue.analysis.InterCollection.CAuxiliaryData;
import org.rescue.analysis.InterDimension.DAuxiliaryData;

public class TestTaxonomy {

	public DirectedAcyclicGraph load (char o) {
		DirectedAcyclicGraph cah;
		switch (o) {
		case 's':
			cah = loadForSummarize();
			break;
		case 'c':
			cah = loadForCollCompare();
			break;
//		case 'd': 
//			cah = loadForDimCompare();
//			break;
		default: 
			System.out.println("Invalid operator.");
		cah = null;
		break;	
		}
		return cah;	 
	}


	public DirectedAcyclicGraph loadForSummarize() {
		DirectedAcyclicGraph cah = new DirectedAcyclicGraph();
		try {
			// Define concepts:
			Concept c1 = new Concept(1);
			Concept c2 = new Concept(2);
			Concept c3 = new Concept(3);
			Concept c4 = new Concept(4);
			Concept c5 = new Concept(5);
			Concept c6 = new Concept(6);
			Concept c7 = new Concept(7);
			Concept c8 = new Concept(8);
			Concept c9 = new Concept(9);
			Concept c10 = new Concept(10);
			Concept c11 = new Concept(11);
			Concept c12 = new Concept(12);
			Concept c13 = new Concept(13);
			Concept c14 = new Concept(14);
			Concept c15 = new Concept(15);
			Concept c16 = new Concept(16);
			Concept c17 = new Concept(17);
			Concept c18 = new Concept(18);
			Concept c19 = new Concept(19);
			Concept c20 = new Concept(20);
			Concept c21 = new Concept(21);
			Concept c22 = new Concept(22);
			
			c2.dCard = 0;
			c4.dCard = 1;
			c10.dCard = 5;
			c11.dCard = 2;
			c14.dCard = 5;
			c15.dCard = 3;
			c13.dCard = 20;
			c5.dCard = 10;
			c6.dCard = 1;
			c8.dCard = 1;
			c9.dCard = 16;
			c3.dCard = 3;

			// c1.card = 69;			

			// First subtree:
			cah.addRelationship(c1, c2,true);
			cah.addRelationship(c1, c3,true);
			cah.addRelationship(c3, c7,true);
			cah.addRelationship(c2, c4,true);
			cah.addRelationship(c2, c5,true);
			cah.addRelationship(c2, c6,true);
			cah.addRelationship(c4, c10,true);
			cah.addRelationship(c4, c11,true);
			cah.addRelationship(c4, c12,true);
			cah.addRelationship(c4, c13,true);
			cah.addRelationship(c7, c8,true);
			cah.addRelationship(c7, c9,true);
			cah.addRelationship(c12, c14,true);
			cah.addRelationship(c12, c15,true);

			// Second subtree:
			cah.addRelationship(c20, c21,true);
			cah.addRelationship(c20, c22,true);
			cah.addRelationship(c21, c12,true);
			cah.addRelationship(c21, c9,true);

			// Print taxonomy:
			cah.printRelationships();
			System.out.println("numberOfRelationships = " + cah.getNumberOfRelationships());

		}
		catch (Exception ex) {
			ex.printStackTrace();
		};
		return cah;
	}

	public DirectedAcyclicGraph loadForCollCompare() {
		DirectedAcyclicGraph cah = new DirectedAcyclicGraph();
		try {
			// Define concepts:
			Concept y1 = new Concept(1);
			Concept y2 = new Concept(2);
			Concept y3 = new Concept(3);
			Concept y4 = new Concept(4);
			Concept y5 = new Concept(5);
			Concept y6 = new Concept(6);
			Concept y7 = new Concept(7);
			Concept y8 = new Concept(8);

			CAuxiliaryData auxData;
			y1.dCard = 11;
			auxData = new CAuxiliaryData();
			auxData.dCard = 9; 
			y1.setAuxData(auxData);

			y2.dCard = 9;
			auxData = new CAuxiliaryData();
			auxData.dCard = 13; 
			y2.setAuxData(auxData);

			y3.dCard = 12;
			auxData = new CAuxiliaryData();
			auxData.dCard = 12; 
			y3.setAuxData(auxData);

			y4.dCard = 2;
			auxData = new CAuxiliaryData();
			auxData.dCard = 5; 
			y4.setAuxData(auxData);

			y5.dCard = 5;
			auxData = new CAuxiliaryData();
			auxData.dCard = 1; // smoothing 
			y5.setAuxData(auxData);

			y6.dCard = 0;
			auxData = new CAuxiliaryData();
			auxData.dCard = 0; // smoothing 
			y6.setAuxData(auxData);

			y7.dCard = 0;
			auxData = new CAuxiliaryData();
			auxData.dCard = 0; // smoothing 
			y7.setAuxData(auxData);

			y8.dCard = 0;
			auxData = new CAuxiliaryData();
			auxData.dCard = 0; // smoothing 
			y8.setAuxData(auxData);

			// First subtree:
			cah.addRelationship(y6, y1,true);
			cah.addRelationship(y6, y2,true);
			cah.addRelationship(y6, y3,true);
			cah.addRelationship(y7, y3,true);
			cah.addRelationship(y7, y4,true);
			cah.addRelationship(y7, y5,true);
			cah.addRelationship(y8, y6,true);
			cah.addRelationship(y8, y7,true);

			// Print taxonomy:
			cah.printRelationships();
			System.out.println("numberOfRelationships = " + cah.getNumberOfRelationships());

		}
		catch (Exception ex) {
			ex.printStackTrace();
		};
		return cah;
	}	

	public DirectedAcyclicGraph loadForDimCompare(HashMap <Integer, Integer> bgConcepts) {
		/* Algorithm:
		 * (1) Read the document annotations to count concept occurrences by loading
		 *     to a hashtable (create Concept objects too).
		 * (2) Join the hashtable to the taxonomy to extract the subtaxonomy. 
		 * (3) Combine Concept objects of step 1 and relations of step 2 to
		 *     load the DAG.
		 */		
		DirectedAcyclicGraph origTax = new DirectedAcyclicGraph();
		try {

			// fg_conc_id, bg_conc_id, count
			int [][] aggregateAnnot = {{1,1,11}, {1,2,0}, {1,3,9},{1,4,0},
							  {2,1,9}, {2,2,0}, {2,3,13},{2,4,0},
							  {3,1,12}, {3,2,10}, {3,3,12},{3,4,0},
							  {4,1,2}, {4,2,0}, {4,3,5},{4,4,12},
							  {5,1,5}, {5,2,0}, {5,3,0},{5,4,0}};
			
			HashMap <Integer, Concept> fgConcepts = new HashMap <Integer, Concept>();
			
			// for each FG concept, add to fgConcepts. If absent, add. If present,
			// add bg concept, count pair. Update total count.
			for (int i = 0;  i < 20; ++i) {
				if (aggregateAnnot[i][2] > 0) {
					if (fgConcepts.containsKey(aggregateAnnot[i][0])) {
						Concept c = fgConcepts.get(aggregateAnnot[i][0]); 
						c.dCard += aggregateAnnot[i][2];
						DAuxiliaryData d = (DAuxiliaryData)c.getAuxData();
						d.addBGConcept(aggregateAnnot[i][1],aggregateAnnot[i][2]);
					}
					else {
						Concept c = new Concept(aggregateAnnot[i][0]);
						c.dCard += aggregateAnnot[i][2];
						DAuxiliaryData d = new DAuxiliaryData();    				
						d.addBGConcept(aggregateAnnot[i][1],aggregateAnnot[i][2]);
						c.setAuxData(d);
						fgConcepts.put(aggregateAnnot[i][0],c);
					}
					// add to bgConcepts
					if (bgConcepts.containsKey(aggregateAnnot[i][1])) {
						int count = bgConcepts.get(aggregateAnnot[i][1])+ aggregateAnnot[i][2];
						bgConcepts.put(aggregateAnnot[i][1],count); 	
					}
					else {
						bgConcepts.put(aggregateAnnot[i][1],aggregateAnnot[i][2]);
					}
				}
			}			
			
			// Then, find parent of each concept and add to DAG.
			// Define concepts:
			Concept y1 = new Concept(1);
			Concept y2 = new Concept(2);
			Concept y3 = new Concept(3);
			Concept y4 = new Concept(4);
			Concept y5 = new Concept(5);
			Concept y6 = new Concept(6);
			DAuxiliaryData d = new DAuxiliaryData();
			y6.setAuxData(d);
			Concept y7 = new Concept(7);
			d = new DAuxiliaryData();
			y7.setAuxData(d);
			Concept y8 = new Concept(8);
			d = new DAuxiliaryData();
			y8.setAuxData(d);
		
			origTax.addRelationship(y6, y1,true);
			origTax.addRelationship(y6, y2,true);
			origTax.addRelationship(y6, y3,true);
			origTax.addRelationship(y7, y3,true);
			origTax.addRelationship(y7, y4,true);
			origTax.addRelationship(y7, y5,true);
			origTax.addRelationship(y8, y6,true);
			origTax.addRelationship(y8, y7,true);
			
			Set<Map.Entry<Integer,Concept>> entries = fgConcepts.entrySet();
			for(Map.Entry<Integer,Concept> entry : entries) {
			     Concept c = entry.getValue();
			     DAGNode n = origTax.findNodeOfConcept(c);
			     n.setNodeConcept(c);
			    
			     /*
			     // test
			     Concept cc = origTax.findConcept(c);
			     System.out.println ("FG Concept: " + entry.getKey() + " " + cc.dCard);
			     ((DAuxiliaryData)cc.getAuxData()).printBGConcepts();
			     */
			}
			
			/*
			// Test 
		    System.out.println ("***Total BG Concept counts ***");
			Set<Map.Entry<Integer,Integer>> bgentries = bgConcepts.entrySet();
			for(Map.Entry<Integer,Integer> entry : bgentries) {
			    int key = entry.getKey();
			    int count = entry.getValue();
			    System.out.println (key + " " + count);
			}
			*/

			// Print taxonomy:
			origTax.printRelationships();
			System.out.println("numberOfRelationships = " + origTax.getNumberOfRelationships());

		}
		catch (Exception ex) {
			ex.printStackTrace();
		};
		return origTax;
	}	

}
